<?php
/**
 * This class represent the concept Artist
 *
 * @author Pouja
 */
class Artist {
    private $id;
    private $albums;
    private $name;
    private $careerInformation;
    private $listened;
    private $genres;
    private $yearActive;
    private $similarArtist;
    private $search;
   
    /**
     * Constructor
     */
    public function Artist(){
        $this->albums=array();
        $this->genres=array();
        $this->similarArtist=array();
        $this->search=array();
    }
    
    /**
     * Adds a track to the search array
     * @param Track $track  The track
     */
    public function addSearchTrack($track){
        array_push($this->search,$track);
    }
    
    /**
     * Returns the id of the artist
     * @return int the id of the artist
     */
    public function id(){
        return $this->id;
    }
    
    /**
     * Sets the id of the artist
     * @param int $id The id
     */
    public function setID($id){
        if(is_int((int)$id)){
            $this->id=(int)$id;
        }
    }
    
    /** DEPRECATED
     * Returns the id of the artist, same as id()
     * @return int The id of the artist
     */
    public function getID(){
        return $this->id;
    }
    
    /**
     *
     * @return Album all the albums that this artist has
     */
    public function albums(){
        return $this->albums;
    }
    
    /** 
     * Returns number of tracks the artist has
     * @return int The count 
     */
    public function numTracks(){
        $count = 0;
        foreach($this->albums as $a){
            $count += count($a->songs());
        }
        return $count;
    }
    
    /**
     *
     * @return String The name of the artist
     */
    public function name(){
        return $this->name;
    }
    
    /**
     *
     * @return String The career information about this artist 
     */
    public function careerInformation(){
        return $this->careerInformation;
    }
    
    /**
     *
     * @return int Number of times people listened to this artist
     */
    public function listened(){
        return $this->listened;
    }
    /**
     * Sets the listen count of the artist
     * @param int $listeners The listen ocunt
     */
    public function setListeners($listeners){
        $this->listened=$listeners;
    }
    /**
     *
     * @return Array Genres 
     */
    public function genres(){
        return $this->genres;
    }
    /**
     * The first key is the year that the artist started <br>
     * The second key is the year that the artist stopped
     * @return Array The year in which the artist was active 
     */
    public function yearActive(){
        return $this->yearActive;
    }
    
    /**
     * Checks whether the artist has the track
     * @param String $trackName The track name
     * @return true if the track is in one of the album that this artist has 
     */
    public function hasTrack($trackName){
        for($i=0;$i<count($this->albums);$i++)
        {
            $album = $this->albums[$i];
            $tracks=$album->songs();
            for($j=0;$j<count($tracks);$j++)
            {
                
                if(strcmp($trackName,$tracks[$j]->name())==0){
                    return true;
                }
            }
        } 
        return false;
    }
    
    /**
     *
     * @param Album $album The album that must be searched for
     * @return int -1 if $album doesn't exist in the array<br>
     * @return int N if $album does exist returns the key 
     */
    private function keyAlbum($album){
        if($album instanceof Album){
            for($i=0;$i<count($this->albums);$i++){
                if($album->equals($this->albums[$i])){
                    return $i;
                }
            }
        }
        return -1;
    }
    
    /**
     * Checks if the artist has the album
     * @param String $albumName the album name
     * @return boolean true if the album has the album, false otherwise 
     */
    public function hasAlbum($albumName){
        for($i=0;$i<count($this->albums);$i++){
            //print($albumName." COMPARE ".$this->albums[$i]->name()." RESULT ".strcmp($albumName,$this->albums[$i]->name())."<br><br>");
            if(strcmp($albumName,$this->albums[$i]->name())==0){
                return true;
            }
        } 
        return false;
    }
    
    /**
     *
     * @param Album $album The album that must be added
     * @return boolean True if the album is added
     * @return boolean False if the album isn't added
     */
    public function addAlbum($album){
        if($this->albums==NULL){
            $this->albums=array();
            array_push($this->albums, $album);
            return true;
        }
        if($this->keyAlbum($album)==-1){
            array_push($this->albums, $album);
            return true;
        }
        return false;
    }
    
    /**
     *
     * @param Album $album The album that must be removed
     * @return boolean true if the album is removed
     * @return boolean false if the album isn't removed 
     */
    public function removeAlbum($album){
        $key=$this->keyAlbum($album);
        if($key!=-1){
            unset($this->albums[$key]);
            return true;
        }
        return false;
    }
    
    /**
     *
     * @param String $genre The genre for which must be searched for
     * @return int -1 if the genre isn't found
     * @return int N if the genre is found return the key
     */
    private function keyGenre($genre){
        if($genre!=NULL){
            for($i=0;$i<count($this->genres);$i++){
                if(strcmp($this->genres[$i],$genre)==0){
                    return $i;
                }
            }
        }
        return -1;
    }
    
    /**
     *
     * @param String $genre The genre that must be added
     * @return boolean true if the genre is added
     * @return boolean false if the genre isn't added 
     */
    public function addGenre($genre){
        if($this->genres==NULL){
            $this->genres=array();
            array_push($this->genres, $genre);
            return true;
        }
        if($this->keyGenre($genre)==-1){
            array_push($this->genres, $genre);
            return true;
        }
        return false;
    }
    
    /**
     *
     * @param type $genre
     * @return type 
     */
    public function removeGenre($genre){
        $key=$this->keyGenre($genre);
        if($key!=-1){
            unset($this->keyGenre[$key]);
            return true;
        }
        return false;
    }
    
    /** 
     * Returns the index of the array similar of the simliar artist
     * @param Artist $artist The artist object
     * @return int index The index of the similar artist, -1 if similar artist isn't in the array similar
     */
    private function keySimilar($artist){
        if($artist instanceof Artist){
            for($i=0;$i<count($this->similarArtist);$i++){
                if($artist->equals($this->similarArtist[$i])){
                    return $i;
                }
            }
        }
        return -1;
    }
    
    /**
     * Adds a similar artist to the similar array
     * @param Artist $artist The similar artist
     * @return boolean true If the similar artist is been added, false otherwise 
     */
    public function addSimilar($artist){
        //if($artist instanceof Artist){
            if($this->keySimilar($artist)==-1){
                array_push($this->similarArtist, $artist);
                return true;
            }
       // }
        return false;
    }

    /**
     * Returns all the similar artists
     * @return type array of similar artists
     */
    public function similar(){
        return $this->similarArtist;
    }
    /**
     * DEPRECATED
     * @param int $key The index
     * @param Artist $artist The artist object
     * @return Artist artist The artist object
     */
    public function getSimilar($key,$artist=null){
        if(is_int($key) && $artist==null){
            if(count($this->similarArtist)>$key){
                return $this->similarArtist[$key];
            }
        }
        if($artist!=null){
            $key=$this->keySimilar($artist);
            if($key!=-1){
                return $this->similarArtist[$key];
            }
        }
        return null;
    }
    
    /**
     * Sets the name of the artist
     * @param String $name The name
     */
    public function setName($name){
        $this->name=$name;
    }
        
    /**
     * Sets the career information of the artist
     * @param String $info The career information
     */
    public function setCareerInformation($info){
        $this->careerInformation=$info;
    }
    
    /**
     * Increase the number of times users listened to this artist with 1
     */
    public function addListener(){
        $this->listened++;
    }
    
    /**
     * Sets the year active
     * @param int $from The start year
     * @param int $to The end year
     */
    public function setYearActive($from,$to){
        if($this->yearActive==NULL){
            $this->yearActive=array();
        }
        $this->yearActive[0]=$from;
        $this->yearActive[1]=$to;
    }
    
    /**
     * Equals methode, two artist are the same if the name are an exact match
     * @param Artist $that The artist to be compared
     * @return boolean true If the artists have the same name, false otherwise 
     */
    public function equals($that){
        if($that instanceof Artist){
            if(strcmp($that->name(), $this->name)==0){
                return true;
            }
        }
        return false;
    }
    
    /**
     * Returns a string representation of this object
     * @return string representation
     */
    public function toString(){
        $out='';
            $out.='Artist['.$this->name.',';
        /*$out.=$this->careerInformation.',';
        $out.='Albums[';
        foreach($this->albums as $album){
            $out.=$album->toString().',';
        }*/
        $out.=']Genres[';
        foreach($this->genres as $genre){
            $out.=$genre.',';
        }
        $out.=']'.$this->listened.',';
        if($this->yearActive!=NULL){
            $out.=$this->yearActive[0].','.$this->yearActive[1];
        }
        $out.=']';
        $out.='Similar[';
        foreach($this->similarArtist as $similar){
            if($similar instanceof Artist){
            $out.=$similar->toString().',';
            }
            else{
                $out.=$similar.',';
            }
        }
        
        return $out;
    }
    
    /**
     * @return an JSON format of this class
     */
    public function toJSON(){
        $out=array();
        $out['id']=$this->id;
        $out['name']=$this->name;
        $out['yearActive']=$this->yearActive;
        $out['albums']=array();
        if($this->albums!=null){
            if($this->albums[0] instanceof Album){
                foreach($this->albums as $album){
                    array_push($out['albums'],$album->toJSON());
                }
            }
            else{
                foreach($this->albums as $album){
                    array_push($out['albums'],$album);
                }
            }
        }
        $out['listened']=$this->listened;
        $out['genres']=$this->genres;
        $out['similars']=array();
        if($this->similarArtist!=null){
            if($this->similarArtist[0] instanceof Artist){
                foreach($this->similarArtist as $artist){
                    array_push($out['similars'],$artist->toJSON());
                }
            }
            else{
                foreach($this->similarArtist as $artist){
                    array_push($out['similars']);
                }
            }
        }
        $out['search']=array();
        foreach($this->search as $track){
            if($track instanceof Track)
                array_push($out['search'],$track->toJSON());
        }
        $out['careerInformation']=$this->careerInformation;
        return $out;
    }

    /**
     * Sets the albums of the artist
     * @param Array $albums The albums
     */
    public function setAlbums($albums){
        $this->albums=$albums;
    }
}
?>
